package com.hand.qiandu.interceptor;

import com.alibaba.fastjson.JSON;
import com.hand.qiandu.annotation.PermissAnnotation;
import com.hand.qiandu.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.thymeleaf.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

/**
 * @author 24748  刘瑞锋
 * @date 2019/7/17
 */
@Component
public class ControllerInterceptor implements HandlerInterceptor {

    @Autowired
    private IUserService userService;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("ControllerInterceptor:  preHandle" );
        //为true才会继续执行，false的话被拦截 可用做校验
        boolean validate = false;
        //判断是否这个请求URI和method是否需要校验
        if(isValidate(handler)){
            //这个URI需要校验，返回是否检验成功
            validate = validateUserPermission(request);
        }
        if(validate){
            System.out.println(request.getRequestURI());
            //校验成功
            return true;
        }else {
            //检验失败
            ErrorMsg errorMsg = new ErrorMsg("permission.not.find","用户无权限");
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/json");
            //设置响应码
            response.setStatus(HttpStatus.FORBIDDEN.value());
            PrintWriter writer = response.getWriter();
            String msg = JSON.toJSONString(errorMsg);
            writer.print(msg);
            writer.close();
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("ControllerInterceptor:  postHandle" );

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("ControllerInterceptor:  afterCompletion" );
    }


    private Boolean validateUserPermission(HttpServletRequest request) {
        Boolean result = false;
        //获取请求头的userId字段
        String userId = request.getHeader("userId");
        if (!StringUtils.isEmpty(userId)) {
            /*           获取对应userId的权限信息             */
            List<Map<String, String>> permissionMap = userService.queryUserPermission(Long.valueOf(userId));
            String uri = request.getRequestURI();
            String method = request.getMethod();
            AntPathMatcher matcher = new AntPathMatcher();
//            for(int i = 0;i < permissionMap.size(); i++){
//                if(permissionMap.get(i).get("path").equals(uri) && permissionMap.get(i).get("method").equals(method)){
//                    result = true;
//                    break;
//                }
//            }
            for (Map<String, String> map : permissionMap) {
                if (matcher.match(map.get("path"), uri) && map.get("method").equals(method)) {
                    result = true;
                    break;
                }
            }
        }
    return result;
    }

    //判断是否要做权限检验
    private Boolean isValidate(Object handler) {
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        //获取请求的方法
        Method method = handlerMethod.getMethod();
        //获取方法上注解
        PermissAnnotation methodAnnotation = method.getAnnotation(PermissAnnotation.class);
        //方法上是否有需要权限校验的注解，如果不为空，返回注解上value的值,如果方法上没有注解，判断该方法的类上是否有注解
        if (null!=methodAnnotation) {
            return methodAnnotation.value();
        }else {
            //获取类的注解
            PermissAnnotation classAnnotation = method.getDeclaringClass().getAnnotation(PermissAnnotation.class);
            if (!("".equals(classAnnotation) || classAnnotation == null)) {
                //如果类上有这个注解，返回注解中的value值
                return classAnnotation.value();
            }

        }
        return false;
    }
}
